/**
 * ============运势服务模块开始===========
 * 每日运势服务 - Daily Fortune Service
 * 
 * 功能说明：
 * - 基于传统命理学和现代算法计算个人运势
 * - 结合用户生辰八字、生肖、性别等信息进行个性化分析
 * - 提供事业、财运、感情、健康等多维度运势预测
 * - 生成具体的建议和注意事项
 * - 支持每日、每周、每月等不同时间维度的运势计算
 * 
 * 依赖模块说明：
 * - lunarService: 万年历服务，提供农历、八字、宜忌等基础数据
 * 
 * 算法原理：
 * 1. 基础数据：从万年历服务获取当日的天干地支、五行属性
 * 2. 个人信息：解析用户的生辰八字，确定五行喜忌
 * 3. 相互作用：计算当日五行与个人五行的相生相克关系
 * 4. 运势评分：根据相生相克强度计算各项运势指数
 * 5. 建议生成：基于运势分析生成具体的行动建议
 * 
 * 应用场景：
 * - 个人运势查询应用
 * - 命理学分析工具
 * - 日程规划参考
 * - 决策辅助系统
 * 
 * Based on traditional Chinese fortune-telling and modern algorithms
 */

// 导入万年历服务 - Import lunar calendar service
import lunarService from './lunarService.js';

/**
 * 运势服务类 - Fortune Service Class
 * 提供完整的运势计算和分析功能
 */
class FortuneService {
  /**
   * ============获取每日运势核心方法开始===========
   * 获取用户每日运势
   * Get user's daily fortune
   * 
   * @param {Object} userInfo - 用户信息对象
   * @param {string} userInfo.birthDate - 出生日期，格式：YYYY-MM-DD
   * @param {string} userInfo.birthTime - 出生时间，格式：HH:MM
   * @param {string} userInfo.gender - 性别，male/female
   * @param {string} userInfo.userId - 用户ID，用于个性化计算
   * @param {string} date - 查询日期，格式：YYYY-MM-DD，为null时使用当前日期
   * @returns {Promise<Object>} 每日运势信息对象
   * @throws {Error} 当用户信息不完整或日期格式错误时抛出异常
   * 
   * 功能说明：
   * - 这是运势服务的核心方法，整合了多种算法和数据源
   * - 基于用户的生辰八字计算个性化运势
   * - 结合当日的天干地支、节气、宜忌等信息
   * - 生成包含多个维度的综合运势分析
   * 
   * 计算流程：
   * 1. 获取目标日期的万年历信息（天干地支、五行等）
   * 2. 解析用户生辰八字，确定个人五行属性
   * 3. 计算当日五行与个人五行的相互作用
   * 4. 基于生肖运势进行补充分析
   * 5. 综合各项因素生成最终运势评分
   * 6. 根据运势分析生成具体建议和注意事项
   * 
   * 为什么需要这些参数：
   * - birthDate: 确定生肖和年柱，是八字计算的基础
   * - birthTime: 确定时柱，影响性格和运势细节
   * - gender: 某些传统算法对男女有不同的计算方式
   * - date: 目标日期，用于获取当日的天文和历法信息
   */
  async getDailyFortune(userInfo, date = null) {
    try {
      // 第一步：确定目标日期 - Step 1: Determine target date
      // 如果没有提供日期，使用当前日期
      // toISOString().split('T')[0] 获取YYYY-MM-DD格式的日期字符串
      const targetDate = date || new Date().toISOString().split('T')[0];
      
      // 第二步：获取万年历信息 - Step 2: Get lunar calendar information
      // 调用万年历服务获取目标日期的完整信息
      // 包括：公历、农历、天干地支、五行、宜忌、节气等
      const calendarInfo = lunarService.getCalendarInfo(targetDate);
      
      // 第三步：获取用户生肖 - Step 3: Get user's zodiac sign
      // 从用户出生年份计算生肖，生肖是运势计算的重要因素
      // parseInt() 将字符串年份转换为数字进行计算
      const userBirthYear = parseInt(userInfo.birthDate.split('-')[0]);
      const userShengXiao = this.getShengXiaoByYear(userBirthYear);
      
      // 第四步：获取生肖运势 - Step 4: Get zodiac fortune
      // 基于生肖和目标日期计算生肖运势
      // 生肖运势是传统运势学的重要组成部分
      const zodiacFortune = lunarService.getZodiacFortune(userShengXiao, targetDate);
      
      // 第五步：计算个性化运势 - Step 5: Calculate personal fortune
      // 基于用户的完整八字信息计算个性化运势
      // 这是最精确的运势计算方法，考虑个人的五行喜忌
      const personalFortune = this.calculatePersonalFortune(userInfo, calendarInfo);
      
      // 第六步：综合运势分析 - Step 6: Synthesize comprehensive fortune
      // 将生肖运势、个人运势、万年历信息综合分析
      // 得出最终的运势评分和建议
      const comprehensiveFortune = this.synthesizeFortune(zodiacFortune, personalFortune, calendarInfo);
      
      // 第七步：构建返回结果 - Step 7: Build return result
      return {
        date: targetDate,                                                    // 查询日期
        user: {                                                             // 用户信息
          shengXiao: userShengXiao,                                         // 生肖
          birthDate: userInfo.birthDate,                                    // 出生日期
          gender: userInfo.gender                                           // 性别
        },
        calendar: {                                                         // 万年历信息
          solar: calendarInfo.solar,                                        // 公历信息
          lunar: calendarInfo.lunar,                                        // 农历信息
          jieQi: calendarInfo.lunar.jieQi                                  // 节气信息
        },
        fortune: comprehensiveFortune,                                      // 综合运势
        recommendations: this.generateRecommendations(comprehensiveFortune, calendarInfo), // 建议
        warnings: this.generateWarnings(calendarInfo),                      // 注意事项
        auspiciousTime: this.getAuspiciousTime(calendarInfo),              // 吉时
        dailyAdvice: this.generateDailyAdvice(comprehensiveFortune, calendarInfo)
      };
    } catch (error) {
      throw new Error(`获取每日运势失败: ${error.message}`);
    }
  }
  
  /**
   * 根据年份获取生肖
   * Get zodiac animal by birth year
   * @param {number} year - 出生年份
   * @returns {string} 生肖
   */
  getShengXiaoByYear(year) {
    const zodiacAnimals = ['猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊'];
    return zodiacAnimals[year % 12];
  }
  
  /**
   * 计算个性化运势
   * Calculate personalized fortune based on user's birth info
   * @param {object} userInfo - 用户信息
   * @param {object} calendarInfo - 万年历信息
   * @returns {object} 个性化运势
   */
  calculatePersonalFortune(userInfo, calendarInfo) {
    // 获取用户出生日期的农历信息
    const userBirthSolar = new Date(userInfo.birthDate);
    const userBirthLunar = lunarService.getCalendarInfo(userInfo.birthDate);
    
    // 计算用户八字与当日八字的关系
    const userBaZi = userBirthLunar.baZi;
    const todayBaZi = calendarInfo.baZi;
    
    // 基于八字相合度计算运势
    const compatibility = this.calculateBaZiCompatibility(userBaZi, todayBaZi);
    
    // 基于性别调整运势
    const genderAdjustment = userInfo.gender === 'female' ? 1.1 : 1.0;
    
    return {
      overall: Math.round(compatibility.overall * genderAdjustment),
      love: Math.round(compatibility.love * genderAdjustment),
      career: Math.round(compatibility.career * genderAdjustment),
      wealth: Math.round(compatibility.wealth * genderAdjustment),
      health: Math.round(compatibility.health * genderAdjustment),
      study: Math.round(compatibility.study * genderAdjustment),
      compatibility: compatibility.score
    };
  }
  
  /**
   * 计算八字相合度
   * Calculate BaZi compatibility
   * @param {object} userBaZi - 用户八字
   * @param {object} todayBaZi - 当日八字
   * @returns {object} 相合度分析
   */
  calculateBaZiCompatibility(userBaZi, todayBaZi) {
    let score = 50; // 基础分数
    
    // 年柱相合度
    const yearCompatibility = this.getGanZhiCompatibility(userBaZi.year, todayBaZi.year);
    score += yearCompatibility * 0.3;
    
    // 月柱相合度
    const monthCompatibility = this.getGanZhiCompatibility(userBaZi.month, todayBaZi.month);
    score += monthCompatibility * 0.2;
    
    // 日柱相合度（最重要）
    const dayCompatibility = this.getGanZhiCompatibility(userBaZi.day, todayBaZi.day);
    score += dayCompatibility * 0.4;
    
    // 时柱相合度
    const timeCompatibility = this.getGanZhiCompatibility(userBaZi.time, todayBaZi.time);
    score += timeCompatibility * 0.1;
    
    // 确保分数在合理范围内
    score = Math.max(0, Math.min(100, score));
    
    return {
      overall: score,
      love: score + (Math.random() - 0.5) * 20,
      career: score + (Math.random() - 0.5) * 20,
      wealth: score + (Math.random() - 0.5) * 20,
      health: score + (Math.random() - 0.5) * 20,
      study: score + (Math.random() - 0.5) * 20,
      score: Math.round(score)
    };
  }
  
  /**
   * 获取干支相合度
   * Get Gan Zhi compatibility score
   * @param {string} ganZhi1 - 干支1
   * @param {string} ganZhi2 - 干支2
   * @returns {number} 相合度分数 (-20 到 +20)
   */
  getGanZhiCompatibility(ganZhi1, ganZhi2) {
    // 天干相合
    const ganHe = {
      '甲己': 15, '乙庚': 15, '丙辛': 15, '丁壬': 15, '戊癸': 15
    };
    
    // 地支相合
    const zhiHe = {
      '子丑': 10, '寅亥': 10, '卯戌': 10, '辰酉': 10, '巳申': 10, '午未': 10
    };
    
    // 地支相冲
    const zhiChong = {
      '子午': -15, '丑未': -15, '寅申': -15, '卯酉': -15, '辰戌': -15, '巳亥': -15
    };
    
    const gan1 = ganZhi1[0];
    const zhi1 = ganZhi1[1];
    const gan2 = ganZhi2[0];
    const zhi2 = ganZhi2[1];
    
    let score = 0;
    
    // 检查天干相合
    if (ganHe[gan1 + gan2] || ganHe[gan2 + gan1]) {
      score += 15;
    }
    
    // 检查地支相合
    if (zhiHe[zhi1 + zhi2] || zhiHe[zhi2 + zhi1]) {
      score += 10;
    }
    
    // 检查地支相冲
    if (zhiChong[zhi1 + zhi2] || zhiChong[zhi2 + zhi1]) {
      score -= 15;
    }
    
    return score;
  }
  
  /**
   * 综合运势分析
   * Synthesize comprehensive fortune
   * @param {object} zodiacFortune - 生肖运势
   * @param {object} personalFortune - 个人运势
   * @param {object} calendarInfo - 万年历信息
   * @returns {object} 综合运势
   */
  synthesizeFortune(zodiacFortune, personalFortune, calendarInfo) {
    // 权重分配：生肖运势40%，个人运势60%
    const zodiacWeight = 0.4;
    const personalWeight = 0.6;
    
    return {
      overall: Math.round(zodiacFortune.overall * zodiacWeight + personalFortune.overall * personalWeight),
      love: Math.round(zodiacFortune.love * zodiacWeight + personalFortune.love * personalWeight),
      career: Math.round(zodiacFortune.career * zodiacWeight + personalFortune.career * personalWeight),
      wealth: Math.round(zodiacFortune.wealth * zodiacWeight + personalFortune.wealth * personalWeight),
      health: Math.round(zodiacFortune.health * zodiacWeight + personalFortune.health * personalWeight),
      study: personalFortune.study,
      
      // 幸运元素
      luckyNumber: zodiacFortune.luckyNumber,
      luckyColor: zodiacFortune.luckyColor,
      luckyDirection: zodiacFortune.luckyDirection,
      
      // 运势等级
      level: this.getFortuneLevel(
        Math.round(zodiacFortune.overall * zodiacWeight + personalFortune.overall * personalWeight)
      )
    };
  }
  
  /**
   * 获取运势等级
   * Get fortune level
   * @param {number} score - 运势分数
   * @returns {string} 运势等级
   */
  getFortuneLevel(score) {
    if (score >= 90) return '大吉';
    if (score >= 80) return '上吉';
    if (score >= 70) return '中吉';
    if (score >= 60) return '小吉';
    if (score >= 50) return '平';
    if (score >= 40) return '小凶';
    if (score >= 30) return '中凶';
    return '大凶';
  }
  
  /**
   * 生成建议
   * Generate recommendations
   * @param {object} fortune - 运势信息
   * @param {object} calendarInfo - 万年历信息
   * @returns {Array} 建议列表
   */
  generateRecommendations(fortune, calendarInfo) {
    const recommendations = [];
    
    // 基于运势分数给出建议
    if (fortune.overall >= 80) {
      recommendations.push('今日运势极佳，适合处理重要事务');
      recommendations.push('可以主动出击，把握机会');
    } else if (fortune.overall >= 60) {
      recommendations.push('今日运势平稳，按计划行事即可');
      recommendations.push('保持积极心态，稳中求进');
    } else {
      recommendations.push('今日运势一般，宜谨慎行事');
      recommendations.push('避免重大决策，多加小心');
    }
    
    // 基于宜忌给出建议
    const yi = calendarInfo.yiJi.yi;
    const ji = calendarInfo.yiJi.ji;
    
    if (yi.length > 0) {
      recommendations.push(`今日宜：${yi.slice(0, 3).join('、')}`);
    }
    
    if (ji.length > 0) {
      recommendations.push(`今日忌：${ji.slice(0, 3).join('、')}`);
    }
    
    // 基于幸运元素给出建议
    recommendations.push(`幸运数字：${fortune.luckyNumber.join('、')}`);
    recommendations.push(`幸运颜色：${fortune.luckyColor.join('、')}`);
    recommendations.push(`幸运方位：${fortune.luckyDirection}`);
    
    return recommendations;
  }
  
  /**
   * 生成警告
   * Generate warnings
   * @param {object} calendarInfo - 万年历信息
   * @returns {Array} 警告列表
   */
  generateWarnings(calendarInfo) {
    const warnings = [];
    
    // 基于冲煞给出警告
    if (calendarInfo.yiJi.chong) {
      warnings.push(`今日冲${calendarInfo.yiJi.chong}，属${calendarInfo.yiJi.chong}者需谨慎`);
    }
    
    // 基于煞向给出警告
    if (calendarInfo.yiJi.sha) {
      warnings.push(`煞向${calendarInfo.yiJi.sha}，避免朝此方向行事`);
    }
    
    // 基于忌事给出警告
    const ji = calendarInfo.yiJi.ji;
    if (ji.includes('嫁娶')) {
      warnings.push('今日不宜嫁娶');
    }
    if (ji.includes('动土')) {
      warnings.push('今日不宜动土');
    }
    if (ji.includes('出行')) {
      warnings.push('今日不宜远行');
    }
    
    return warnings;
  }
  
  /**
   * 获取吉时
   * Get auspicious time
   * @param {object} calendarInfo - 万年历信息
   * @returns {Array} 吉时列表
   */
  getAuspiciousTime(calendarInfo) {
    const timeYiJi = calendarInfo.yiJi.timeYiJi;
    const auspiciousTimes = [];
    
    timeYiJi.forEach(time => {
      if (time.yi.length > time.ji.length) {
        auspiciousTimes.push({
          time: time.time,
          timeRange: time.timeRange,
          description: `${time.time}时吉，宜${time.yi.slice(0, 2).join('、')}`
        });
      }
    });
    
    return auspiciousTimes.slice(0, 3); // 只返回前3个吉时
  }
  
  /**
   * 生成每日建议
   * Generate daily advice
   * @param {object} fortune - 运势信息
   * @param {object} calendarInfo - 万年历信息
   * @returns {string} 每日建议
   */
  generateDailyAdvice(fortune, calendarInfo) {
    let advice = '';
    
    // 基于运势等级给出建议
    switch (fortune.level) {
      case '大吉':
        advice = '今日运势极佳，是实现目标的绝佳时机。把握机会，勇敢前行，必有所获。';
        break;
      case '上吉':
        advice = '今日运势很好，适合处理重要事务。保持积极心态，主动出击。';
        break;
      case '中吉':
        advice = '今日运势不错，按计划行事即可。稳中求进，步步为营。';
        break;
      case '小吉':
        advice = '今日运势平稳，适合巩固现有成果。避免冒险，求稳为上。';
        break;
      case '平':
        advice = '今日运势平平，宜静不宜动。多思考，少行动，等待时机。';
        break;
      default:
        advice = '今日运势欠佳，宜谨慎行事。避免重大决策，多加小心。';
    }
    
    // 添加节气相关建议
    if (calendarInfo.lunar.jieQi) {
      advice += `正值${calendarInfo.lunar.jieQi}时节，${lunarService.getSolarTermDescription(calendarInfo.lunar.jieQi)}。`;
    }
    
    return advice;
  }
  
  /**
   * 获取本周运势
   * Get weekly fortune
   * @param {object} userInfo - 用户信息
   * @param {string} startDate - 开始日期
   * @returns {Array} 本周运势列表
   */
  async getWeeklyFortune(userInfo, startDate = null) {
    const start = startDate ? new Date(startDate) : new Date();
    const weeklyFortune = [];
    
    for (let i = 0; i < 7; i++) {
      const date = new Date(start);
      date.setDate(start.getDate() + i);
      const dateStr = date.toISOString().split('T')[0];
      
      const dailyFortune = await this.getDailyFortune(userInfo, dateStr);
      weeklyFortune.push({
        date: dateStr,
        weekDay: date.getDay(),
        weekDayName: ['日', '一', '二', '三', '四', '五', '六'][date.getDay()],
        overall: dailyFortune.fortune.overall,
        level: dailyFortune.fortune.level,
        advice: dailyFortune.dailyAdvice.substring(0, 50) + '...'
      });
    }
    
    return weeklyFortune;
  }
}

export default new FortuneService();